In recent years, programming projects have grown significantly in complexity without a corresponding significant change to the mechanisms in programming languages that are used to control and perform operations such as memory allocation, error handling and language processing. As a result of this lack of change in the mechanisms, software productivity has seen very little improvement despite an abundance of inexpensive hardware. Software projects frequently fail to meet budget or schedule restrictions as a result of the need to perform explicit accident-prone coding.
Computer programs are often divided into high-level interface code that interfaces an application to other applications and users, “middleware” that carries out specific instructions for the application, and “infrastructure”, a layer of code that is concerned with low-level utility issues such as event processing, memory allocation, multi-threading, and error processing. The interface code may be referred to as high-level because it may be conceptualized as sitting on top of the application as the vehicle through which the application interacts with other applications and users. The infrastructure may be referred to as “low-level” as it takes care of basic operations necessary for the application to function. The middleware may be thought of as being the other code in the application that is neither the high-level interface code, nor the low-level infrastructure code and may be conceptualized as being between the two other types of code in an application.
It is frequently the case that information from the high-level interface code is needed in the middleware programs, and high-level interface code and middleware information is needed in the infrastructure. Conventionally there have been two ways to provide higher level information in an application to lower levels. First, information may be left in global or external storage where lower level routines can access it directly. Alternatively, information may be passed down from the higher to lower levels using function arguments. Every function called between the creator of the higher-level information and the ultimate user has to pass the information along, even if the intermediate function does not need the information.
Each method of passing information is subject to certain drawbacks. The global variable method which universally exposes the information works quickly but is subject to bugs. It is difficult or impossible to use the global variable method when there is multi-threading or parallelism in the environment since the global variables may be accessed and/or set by multiple program modules. The information in the global variables which is needed at lower levels may not have not have been stored or updated in global variables, the information may be initially stored in the global variable correctly and then overwritten, or information may be placed in a global variable and then not removed at the proper time with the result that the information remains in the global variables after it is no longer valid.
Unfortunately, the argument passing method also is subject to difficulties. The argument passing method may significantly interfere with the readability and performance of programs. Many middleware routines must pass information from their caller to the functions they call, without this information being used directly. This creates additional overhead in the computing environment. The drawbacks to the global variable method and the argument passing method tend to increase as programs get larger. Typically, information is needed by only a few functions that create the information and a few that use it, but both of these methods make this information available to lots of functions that do not need it. This makes programs harder to understand, since the flow of information is unclear, and when programs are hard to understand, bugs in the programs multiply.
Programmers have attempted to deal with the shortcomings of the global variable method and the argument passing method by creating a context structure or object, which is passed as a single additional argument. However, this has many of the problems of both of the above methods as programs get bigger. The context structure or object method suffers from the difficulties of the global variable method since various fields of the context may be undefined or may have become obsolete. The context structure and object method also suffers from the problems of the argument passing method by giving programs visibility to information that is not needed, while providing difficult access to the information that is needed.
An additional related problem arises frequently when accessing data that is truly global in nature, such as characteristics of the user's screen, settings particular to the hardware (such as rounding mode), and operating system and application options (such as the length or degree of detail of error messages, or whether certain errors should be ignored). It is quite common when dealing with such information that the user creates a temporary variable to hold the previous value of the setting or option, sets the option as desired, and then continues with the computation. At some later time, the option is reset to its earlier setting. Unfortunately, this sort of operation requires additional hand coding and the programmer must remember to restore the proper value at the proper point.